home *** CD-ROM | disk | FTP | other *** search
- /* File: meshsub.c
- ** Author: Charles Loop
- ** Purpose: Contains routines needed for the creation of a subdivided mesh.
- ** Last Modified: 2 July, 1987
- ** Reason : Creation.
- **
- ** new version
- */
-
- #include <stdio.h>
- #include "Math.h"
- #include "4D.h"
- #include "mesh.h"
-
-
- static double a[maxN+1],a_[maxN+1],
- b[maxN+1],b_[maxN+1];
-
- static int FlatShading;
- static int Converge;
-
- /*****************************************************************************/
-
- set_a(l)
- int l;
- {
- double r;
- int i;
-
- for (i = 3; i <= maxN; i++){
- if (l) {
- r = 0.375 + 0.25*cos(TwoPi/i);
- a[i] = r*r + 0.375;
- a_[i] = (1.0 - a[i])/i;
- b[i] = 3.0/(8.0*(1.0 - r*r));
- b_[i] = (1.0 - b[i])/i;
- }
- else {
- b[i] = 1.0;
- b_[i] = 0.0;
- }
- }
- }
-
- /*****************************************************************************/
-
- unsigned OrdAdjList(P,e)
- PointType4D P[];
- Edge *e;
- {
- Edge *ep;
- unsigned N = 1;
-
- if (e) {
- if (e->e) {
- P[0] = *e->next->p;
- for (ep = e->e; ep != e->next && ep != (Edge *) NULL; ep = ep->next->next->e)
- P[N++] = *ep->p;
-
- if (ep)
- return N;
- else
- return 0;
- }
- return 0;
- }
- return 0;
- }
-
- /*****************************************************************************/
-
- Subdivide(Pr,Ps,Pt,pr,ps,pt,qr,qs,qt,Nr,Ns,Nt)
- PointType4D Pr[],Ps[],Pt[],pr[],ps[],pt[],qr[],qs[],qt[];
- unsigned Nr,Ns,Nt;
- {
- PointType4D Vr,Vs,Vt,vr,vs,vt;
- unsigned i;
-
- Vr = Pt[0]; Vs = Pr[0]; Vt = Ps[0];
-
- vr.P[X] = 0.0; vr.P[Y] = 0.0; vr.P[Z] = 0.0;
- vs.P[X] = 0.0; vs.P[Y] = 0.0; vs.P[Z] = 0.0;
- vt.P[X] = 0.0; vt.P[Y] = 0.0; vt.P[Z] = 0.0;
-
- for (i = 0; i < Nr; i++){
- pr[i].P[X] = 0.125*(Pr[(i+Nr-1)%Nr].P[X]+Pr[(i+1)%Nr].P[X])+0.375*(Pr[i].P[X] + Vr.P[X]);
- pr[i].P[Y] = 0.125*(Pr[(i+Nr-1)%Nr].P[Y]+Pr[(i+1)%Nr].P[Y])+0.375*(Pr[i].P[Y] + Vr.P[Y]);
- pr[i].P[Z] = 0.125*(Pr[(i+Nr-1)%Nr].P[Z]+Pr[(i+1)%Nr].P[Z])+0.375*(Pr[i].P[Z] + Vr.P[Z]);
- vr.P[X] = vr.P[X] + Pr[i].P[X];
- vr.P[Y] = vr.P[Y] + Pr[i].P[Y];
- vr.P[Z] = vr.P[Z] + Pr[i].P[Z];
- }
- vr.P[X] = a[Nr]*Vr.P[X] + a_[Nr]*vr.P[X];
- vr.P[Y] = a[Nr]*Vr.P[Y] + a_[Nr]*vr.P[Y];
- vr.P[Z] = a[Nr]*Vr.P[Z] + a_[Nr]*vr.P[Z];
-
- for (i = 0; i < Ns; i++){
- ps[i].P[X] = 0.125*(Ps[(i+Ns-1)%Ns].P[X]+Ps[(i+1)%Ns].P[X])+0.375*(Ps[i].P[X] + Vs.P[X]);
- ps[i].P[Y] = 0.125*(Ps[(i+Ns-1)%Ns].P[Y]+Ps[(i+1)%Ns].P[Y])+0.375*(Ps[i].P[Y] + Vs.P[Y]);
- ps[i].P[Z] = 0.125*(Ps[(i+Ns-1)%Ns].P[Z]+Ps[(i+1)%Ns].P[Z])+0.375*(Ps[i].P[Z] + Vs.P[Z]);
- vs.P[X] = vs.P[X] + Ps[i].P[X];
- vs.P[Y] = vs.P[Y] + Ps[i].P[Y];
- vs.P[Z] = vs.P[Z] + Ps[i].P[Z];
- }
- vs.P[X] = a[Ns]*Vs.P[X] + a_[Ns]*vs.P[X];
- vs.P[Y] = a[Ns]*Vs.P[Y] + a_[Ns]*vs.P[Y];
- vs.P[Z] = a[Ns]*Vs.P[Z] + a_[Ns]*vs.P[Z];
-
- for (i = 0; i < Nt; i++){
- pt[i].P[X] = 0.125*(Pt[(i+Nt-1)%Nt].P[X]+Pt[(i+1)%Nt].P[X])+0.375*(Pt[i].P[X] + Vt.P[X]);
- pt[i].P[Y] = 0.125*(Pt[(i+Nt-1)%Nt].P[Y]+Pt[(i+1)%Nt].P[Y])+0.375*(Pt[i].P[Y] + Vt.P[Y]);
- pt[i].P[Z] = 0.125*(Pt[(i+Nt-1)%Nt].P[Z]+Pt[(i+1)%Nt].P[Z])+0.375*(Pt[i].P[Z] + Vt.P[Z]);
- vt.P[X] = vt.P[X] + Pt[i].P[X];
- vt.P[Y] = vt.P[Y] + Pt[i].P[Y];
- vt.P[Z] = vt.P[Z] + Pt[i].P[Z];
- }
- vt.P[X] = a[Nt]*Vt.P[X] + a_[Nt]*vt.P[X];
- vt.P[Y] = a[Nt]*Vt.P[Y] + a_[Nt]*vt.P[Y];
- vt.P[Z] = a[Nt]*Vt.P[Z] + a_[Nt]*vt.P[Z];
-
- qr[0] = vt; qs[0] = vr; qt[0] = vs;
- qr[1] = pt[0]; qs[1] = pr[0]; qt[1] = ps[0];
- qr[2] = pr[0]; qs[2] = ps[0]; qt[2] = pt[0];
- qr[3] = vs; qs[3] = vt; qt[3] = vr;
- qr[4] = ps[Ns-1]; qs[4] = pt[Nt-1]; qt[4] = pr[Nr-1];
- qr[5] = pt[2]; qs[5] = pr[2]; qt[5] = ps[2];
- qr[6] = qr[0]; qs[6] = qs[0]; qt[6] = qt[0];
- qr[7] = qr[1]; qs[7] = qs[1]; qt[7] = qt[1];
-
- }
-
- /*****************************************************************************/
-
- Plane *PlaneEquation(Vr,Vs,Vt)
- Vertex *Vr,*Vs,*Vt;
- {
- Plane *P;
-
- P = (Plane *)malloc(sizeof(Plane));
-
- P->a = (Vs->y - Vr->y)*(Vt->z - Vr->z) - (Vt->y - Vr->y)*(Vs->z - Vr->z);
- P->b = (Vt->x - Vr->x)*(Vs->z - Vr->z) - (Vs->x - Vr->x)*(Vt->z - Vr->z);
- P->c = (Vs->x - Vr->x)*(Vt->y - Vr->y) - (Vt->x - Vr->x)*(Vs->y - Vr->y);
- P->d = -(P->a*Vr->x + P->b*Vr->y + P->c*Vr->z);
-
- if (fabs(P->a) > fabs(P->b))
- if (fabs(P->a) > fabs(P->c))
- P->maxcomponent = 0;
- else
- P->maxcomponent = 2;
- else if (fabs(P->b) > fabs(P->c))
- P->maxcomponent = 1;
- else
- P->maxcomponent = 2;
-
- return(P);
-
- }
-
- /****************************************************************************/
-
- Vertex *SetVertex(V,P,N)
- PointType4D *V,*P;
- unsigned N;
- {
- Vertex *Q = (Vertex *)malloc(sizeof(Vertex));
- PointType4D Fr0, Fr1, Fi1, Fr2, Fi2;
- double C1, S1, C2, S2, Theta, TwoTheta, tmp;
- unsigned i;
-
- Fr0.P[X] = 0.0; Fr0.P[Y] = 0.0; Fr0.P[Z] = 0.0;
- Fr1.P[X] = 0.0; Fr1.P[Y] = 0.0; Fr1.P[Z] = 0.0;
- Fi1.P[X] = 0.0; Fi1.P[Y] = 0.0; Fi1.P[Z] = 0.0;
- Fr2.P[X] = 0.0; Fr2.P[Y] = 0.0; Fr2.P[Z] = 0.0;
- Fi2.P[X] = 0.0; Fi2.P[Y] = 0.0; Fi2.P[Z] = 0.0;
-
- Theta = TwoPi/N;
- TwoTheta = 2.0*Theta;
-
- for (i = 0; i < N; i++) {
- C1 = cos(Theta*i); S1 = sin(Theta*i);
- C2 = cos(TwoTheta*i); S2 = sin(TwoTheta*i);
-
- Fr0.P[X] += P[i].P[X];
- Fr0.P[Y] += P[i].P[Y];
- Fr0.P[Z] += P[i].P[Z];
-
- Fr1.P[X] += C1*P[i].P[X];
- Fr1.P[Y] += C1*P[i].P[Y];
- Fr1.P[Z] += C1*P[i].P[Z];
- Fi1.P[X] += S1*P[i].P[X];
- Fi1.P[Y] += S1*P[i].P[Y];
- Fi1.P[Z] += S1*P[i].P[Z];
-
- Fr2.P[X] += C2*P[i].P[X];
- Fr2.P[Y] += C2*P[i].P[Y];
- Fr2.P[Z] += C2*P[i].P[Z];
- Fi2.P[X] += S2*P[i].P[X];
- Fi2.P[Y] += S2*P[i].P[Y];
- Fi2.P[Z] += S2*P[i].P[Z];
- }
-
- if (Converge) {
- Q->x = b[N]*V->P[X] + b_[N]*Fr0.P[X];
- Q->y = b[N]*V->P[Y] + b_[N]*Fr0.P[Y];
- Q->z = b[N]*V->P[Z] + b_[N]*Fr0.P[Z];
- } else {
- Q->x = V->P[X];
- Q->y = V->P[Y];
- Q->z = V->P[Z];
- }
-
- Q->a = Fr1.P[Y]*Fi1.P[Z] - Fi1.P[Y]*Fr1.P[Z];
- Q->b = Fr1.P[Z]*Fi1.P[X] - Fi1.P[Z]*Fr1.P[X];
- Q->c = Fr1.P[X]*Fi1.P[Y] - Fi1.P[X]*Fr1.P[Y];
-
- tmp = sqrt(Q->a*Q->a + Q->b*Q->b + Q->c*Q->c);
-
- Q->a = Q->a/tmp;
- Q->b = Q->b/tmp;
- Q->c = Q->c/tmp;
-
- /* compute coefficients of first fundamental form */
- /*
- e = Fr1.P[X]*Fr1.P[X] + Fr1.P[Y]*Fr1.P[Y] + Fr1.P[Z]*Fr1.P[Z];
- f = Fr1.P[X]*Fi1.P[X] + Fr1.P[Y]*Fi1.P[Y] + Fr1.P[Z]*Fi1.P[Z];
- g = Fi1.P[X]*Fi1.P[X] + Fi1.P[Y]*Fi1.P[Y] + Fi1.P[Z]*Fi1.P[Z];
- */
- /* compute coefficients of second fundamental form */
- /*
- l = Q->a*(0.5*(Fr0.P[X] - N*V->P[X]) + Fr2.P[X])
- + Q->b*(0.5*(Fr0.P[Y] - N*V->P[Y]) + Fr2.P[Y])
- + Q->c*(0.5*(Fr0.P[Z] - N*V->P[Z]) + Fr2.P[Z]);
-
- m = Q->a*Fi2.P[X] + Q->b*Fi2.P[Y] + Q->c*Fi2.P[Z];
-
- n = Q->a*(0.5*(Fr0.P[X] - N*V->P[X]) - Fr2.P[X])
- + Q->b*(0.5*(Fr0.P[Y] - N*V->P[Y]) - Fr2.P[Y])
- + Q->c*(0.5*(Fr0.P[Z] - N*V->P[Z]) - Fr2.P[Z]);
- */
- /* compute Gaussian curvature */
- /*
- Q->k = N*N*(l*n - m*m)/(e*g - f*f);
- */
- return(Q);
-
- }
-
- /****************************************************************************/
-
- minmax(r,s,t,m,M)
- double r,s,t,*m,*M;
- {
- if (r > s)
- if (s > t)
- {*M = r; *m = t;}
- else if (r > t)
- {*M = r; *m = s;}
- else
- {*M = t; *m = s;}
- else if (s > t)
- if (r > t)
- {*M = s; *m = t;}
- else
- {*M = s; *m = r;}
- else
- {*M = t; *m = r;}
- }
-
- /****************************************************************************/
-
- Min(a,b,c,d,m)
- double a,b,c,d,*m;
- {
- *m = (a < b) ? a : b;
- *m = (c < *m) ? c : *m;
- *m = (d < *m) ? d : *m;
- }
-
- /****************************************************************************/
-
- Max(a,b,c,d,M)
- double a,b,c,d,*M;
- {
- *M = (a > b) ? a : b;
- *M = (c > *M) ? c : *M;
- *M = (d > *M) ? d : *M;
- }
-
- /****************************************************************************/
-
- CombindBoxes(box,s0,s1,s2,s3)
- double *box;
- Mesh *s0,*s1,*s2,*s3;
- {
-
- Min(s0->box[X][MIN],s1->box[X][MIN],s2->box[X][MIN],s3->box[X][MIN],box);
- Min(s0->box[Y][MIN],s1->box[Y][MIN],s2->box[Y][MIN],s3->box[Y][MIN],box+2);
- Min(s0->box[Z][MIN],s1->box[Z][MIN],s2->box[Z][MIN],s3->box[Z][MIN],box+4);
-
- Max(s0->box[X][MAX],s1->box[X][MAX],s2->box[X][MAX],s3->box[X][MAX],box+1);
- Max(s0->box[Y][MAX],s1->box[Y][MAX],s2->box[Y][MAX],s3->box[Y][MAX],box+3);
- Max(s0->box[Z][MAX],s1->box[Z][MAX],s2->box[Z][MAX],s3->box[Z][MAX],box+5);
-
- }
-
- /****************************************************************************/
-
- Generate(node, Pr, Ps, Pt, Nr, Ns, Nt, l)
- Mesh *node;
- PointType4D Pr[], Ps[], Pt[];
- int Nr, Ns, Nt, l;
- {
- Mesh *submesh;
- PointType4D pr[maxN], ps[maxN], pt[maxN], qr[8], qs[8], qt[8];
- int i;
-
- if (l) {
- node->type = SUBMESH;
-
- submesh = (Mesh *)malloc(4*sizeof(Mesh));
-
- Subdivide(Pr, Ps, Pt, pr, ps, pt, qr, qs, qt, Nr, Ns, Nt);
-
- Generate(submesh , qr+1, qs+1, qt+1, 6, 6, 6, l-1);
- Generate(submesh+1, pr, qt+2, qs, Nr, 6, 6, l-1);
- Generate(submesh+2, qt, ps, qr+2, 6, Ns, 6, l-1);
- Generate(submesh+3, qs+2, qr, pt, 6, 6, Nt, l-1);
-
- CombindBoxes(node->box, submesh, submesh+1, submesh+2, submesh+3);
-
- for (i = 0; i < 3; i++)
- submesh[i].next = submesh+i+1;
-
- node->sub.m = submesh;
-
- }
- else {
- node->type = TRIANGLE;
-
- node->sub.t = (Triangle *)malloc(sizeof(Triangle));
-
- node->sub.t->V[0] = SetVertex(Pt, Pr, Nr);
- node->sub.t->V[1] = SetVertex(Pr, Ps, Ns);
- node->sub.t->V[2] = SetVertex(Ps, Pt, Nt);
-
- minmax(node->sub.t->V[0]->x,node->sub.t->V[1]->x,node->sub.t->V[2]->x,
- &node->box[X][MIN],&node->box[X][MAX]);
- minmax(node->sub.t->V[0]->y,node->sub.t->V[1]->y,node->sub.t->V[2]->y,
- &node->box[Y][MIN],&node->box[Y][MAX]);
- minmax(node->sub.t->V[0]->z,node->sub.t->V[1]->z,node->sub.t->V[2]->z,
- &node->box[Z][MIN],&node->box[Z][MAX]);
-
- node->sub.t->pl = PlaneEquation(node->sub.t->V[0],
- node->sub.t->V[1],
- node->sub.t->V[2]);
- if (FlatShading) {
- node->sub.t->V[0]->a =
- node->sub.t->V[1]->a =
- node->sub.t->V[2]->a = node->sub.t->pl->a;
- node->sub.t->V[0]->b =
- node->sub.t->V[1]->b =
- node->sub.t->V[2]->b = node->sub.t->pl->b;
- node->sub.t->V[0]->c =
- node->sub.t->V[1]->c =
- node->sub.t->V[2]->c = node->sub.t->pl->c;
- }
- }
- }
-
- /****************************************************************************/
-
-
- Traverse(m, level)
- Mesh *m;
- int level;
- {
- Mesh *mp;
- PointType4D Pr[maxN], Ps[maxN], Pt[maxN];
- int Nr, Ns, Nt, i;
-
- if (m) {
- if (m->type == MESH) {
- if (m->sub.m) {
- for (mp = m->sub.m; mp != (Mesh *) 0; mp = mp->next)
- Traverse(mp, level);
-
- for (i = 0; i < 3; i++) {
- m->box[i][MIN] = m->sub.m->box[i][MIN];
- m->box[i][MAX] = m->sub.m->box[i][MAX];
- }
-
- for (mp = m->sub.m->next; mp != (Mesh *) 0; mp = mp->next)
- for (i = 0; i < 3; i++) {
- if (mp->box[i][MIN] < m->box[i][MIN])
- m->box[i][MIN] = mp->box[i][MIN];
- if (mp->box[i][MAX] > m->box[i][MAX])
- m->box[i][MAX] = mp->box[i][MAX];
- }
- }
- }
- else if (m->type == FACE) {
- if (m->sub.e) {
-
- Nr = OrdAdjList(Pr, m->sub.e);
- Ns = OrdAdjList(Ps, m->sub.e->next);
- Nt = OrdAdjList(Pt, m->sub.e->next->next);
-
- if (Nr && Ns && Nt)
- Generate(m, Pr, Ps, Pt, Nr, Ns, Nt, level);
- else
- {
- minmax(Pr[0].P[X], Ps[0].P[X], Pt[0].P[X],
- &m->box[X][MIN],&m->box[X][MAX]);
- minmax(Pr[0].P[Y], Ps[0].P[Y], Pt[0].P[Y],
- &m->box[Y][MIN],&m->box[Y][MAX]);
- minmax(Pr[0].P[Z], Ps[0].P[Z], Pt[0].P[Z],
- &m->box[Z][MIN],&m->box[Z][MAX]);
- }
- }
- }
- }
- }
-
- MeshSub(m, phong, converge, level)
- Mesh *m;
- int phong, converge, level;
- {
-
- if (phong)
- FlatShading = 0;
- else
- FlatShading = 1;
-
- Converge = converge;
-
- set_a(level);
-
-
- MeshPartition(m);
- Traverse(m, level);
-
- }
-
-